/*
 * Created on Jun 10, 2005
 *
 */
package com.erclab.internal.xpresso.webapp.servlets;

import java.io.IOException;
import java.util.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.erclab.internal.xpresso.ReportFactory;
import com.erclab.internal.xpresso.conf.Settings;
import com.erclab.internal.xpresso.dataAccess.Attribute;
import com.erclab.internal.xpresso.dataAccess.DataModifier;
import com.erclab.internal.xpresso.datavalidators.DataValidationError;
import com.erclab.internal.xpresso.exceptions.DataModificationException;
import com.erclab.internal.xpresso.exceptions.ReportException;
import com.erclab.internal.xpresso.reports.Report;
import com.erclab.internal.xpresso.reports.ReportParameters;
import com.erclab.internal.xpresso.security.User;


/**
 * @author Enrique Rodriguez.
 *
 */
public class ReportProcessor extends HttpServlet {

	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
		doPost(request, response);
	}

	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {

		String reportAction = request.getParameter("reportAction");
		HttpSession session = request.getSession();		
		User user = WebUserManagement.loadUser(session, request);
		
		Report theReport;
		try {
			theReport =	ReportFactory.loadReport(request.getParameter("reportName"));
		} catch (Exception e) {
			// TODO log it wiht log4j
			throw new ServletException(e);
		}
		
		ReportParameters parameters = new ReportParameters();
		parameters.setUser((User)session.getAttribute("user"));
		parameters.setUniqueKeyValue(request.getParameter("uniqueKeyValue"));

		HashMap conditions = new HashMap();
		HashMap requestParameters  = new HashMap();
		Enumeration enumer = request.getParameterNames();
		while(enumer.hasMoreElements()){
			String name = (String)enumer.nextElement();
			if (name != null && name.indexOf("Filter") == 0){
				conditions.put(name, request.getParameterValues(name));	
			} else if (name != null && name.indexOf("Param") == 0){
				requestParameters.put(name, request.getParameter(name));			
			}
		}
		parameters.setConditions(conditions);
		parameters.setRequestParameters(requestParameters);		
		theReport.setReportParameters(parameters);
		
		// Check permission to process this report
		if (!Settings.getAccessController().isAllowedToUseResource(theReport, theReport.getReportParameters().getUser())){
			throw new SecurityException("User " + theReport.getReportParameters().getUser().getNetId() 
			+ " is not allowed to use the " + theReport.getReportName() + " report.");
		}
		
		if (theReport.getReportHelper() != null){
			ArrayList keyvalues = getKeyValues(theReport, request);
			try {
				theReport.getReportHelper().processReportChanges(theReport, keyvalues);
			} catch (ReportException e) {
				throw new ServletException("A problem occurred: " + e);
			} catch (DataValidationError e) {
				// TODO Redirect to Report and display error
			}
		}

		if (reportAction != null && reportAction.equals("Delete")){
			String[] elementsToDelete = request.getParameterValues("element");
			DataModifier dm = new DataModifier();
			try {
				dm.deleteElements(theReport, user, elementsToDelete);
			} catch (DataModificationException e) {
				throw new ServletException("A problem occurred trying to delete: " + e);
			}
		}
		response.sendRedirect(createUrlToReport(theReport, request));
	}

	private String createUrlToReport(Report r, HttpServletRequest request) {
		StringBuffer url = new StringBuffer();
		// TODO: Change this to get the extension from properties file 
		url.append(r.getReportName() + ".report?from=ReportProcessor");
		String uniqueKeyValue = r.getReportParameters().getUniqueKeyValue();
		String sortOrder = request.getParameter("sortOrder");
		String pageNum = request.getParameter("pageNum");
		if (isValidParameter(uniqueKeyValue)){
			url.append("&uniqueKeyValue=" + uniqueKeyValue);
		}		
		if (isValidParameter(sortOrder)){
			url.append("&sortOrder=" + sortOrder);
		}	
		if (isValidParameter(pageNum)){
			url.append("&pageNum=" + pageNum);
		}
  		Enumeration paramNames = request.getParameterNames();
		while(paramNames.hasMoreElements()) {
			String paramName = (String)paramNames.nextElement();
			if (paramName != null && paramName.indexOf("Filter") == 0){
				// TODO: URL encode the value
				url.append("&" + paramName + "=" + request.getParameter(paramName));	
			}
		}
		return url.toString();
	}

	private boolean isValidParameter(String uniqueKeyValue) {
		return uniqueKeyValue != null && !uniqueKeyValue.equals("") &&! uniqueKeyValue.equals("null");
	}

	protected ArrayList getKeyValues(Report report, HttpServletRequest request) {
		ArrayList keyValues = new ArrayList();
		Enumeration paramNames = request.getParameterNames();
		while(paramNames.hasMoreElements()) {
			Attribute a = new Attribute();
			String paramName = (String)paramNames.nextElement();
			a.setName(paramName);
			a.setValues(request.getParameterValues(paramName));
			keyValues.add(a);
		}
		return keyValues;
	}

}
